{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Simple Fuctional Api (7.1.1)\n",
    "Single input and Single output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_1 (InputLayer)         [(None, 64)]              0         \n",
      "_________________________________________________________________\n",
      "dense (Dense)                (None, 32)                2080      \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 32)                1056      \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 10)                330       \n",
      "=================================================================\n",
      "Total params: 3,466\n",
      "Trainable params: 3,466\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "from keras import Input, layers, Model\n",
    "input_tensor = Input(shape=(64,))\n",
    "x = layers.Dense(32, activation='relu')(input_tensor)\n",
    "x = layers.Dense(32, activation='relu')(x)\n",
    "output_tensor = layers.Dense(10, activation='softmax')(x)\n",
    "model = Model(input_tensor, output_tensor)\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "8/8 [==============================] - 0s 997us/step - loss: 12.0500\n",
      "Epoch 2/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 13.1539\n",
      "Epoch 3/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 15.2757\n",
      "Epoch 4/10\n",
      "8/8 [==============================] - 0s 2ms/step - loss: 17.5294\n",
      "Epoch 5/10\n",
      "8/8 [==============================] - 0s 2ms/step - loss: 20.2368\n",
      "Epoch 6/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 23.4430\n",
      "Epoch 7/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 27.2277\n",
      "Epoch 8/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 31.5576\n",
      "Epoch 9/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 36.2090\n",
      "Epoch 10/10\n",
      "8/8 [==============================] - 0s 1ms/step - loss: 41.4681\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x1df93044190>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.compile(optimizer='rmsprop', loss='categorical_crossentropy')\n",
    "# Fake Data\n",
    "import numpy as np\n",
    "x_train = np.random.random((1000, 64))\n",
    "y_train = np.random.random((1000, 10))\n",
    "\n",
    "model.fit(x_train, y_train, epochs=10, batch_size=128)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "32/32 [==============================] - 0s 843us/step - loss: 44.3458\n"
     ]
    }
   ],
   "source": [
    "score = model.evaluate(x_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "##########################################################"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Implementing on IMDB Dataset\n",
    "Not Book code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(25000,)\n",
      "(25000,)\n",
      "(25000,)\n",
      "(25000,)\n"
     ]
    }
   ],
   "source": [
    "max_features = 10000   # most common word\n",
    "\n",
    "from tensorflow.keras.datasets import imdb\n",
    "(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)\n",
    "\n",
    "print(x_train.shape)\n",
    "print(y_train.shape)\n",
    "print(x_test.shape)\n",
    "print(y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(25000, 20)\n",
      "(25000,)\n",
      "(25000, 20)\n",
      "(25000,)\n"
     ]
    }
   ],
   "source": [
    "# pad_sequences is used to ensure that all sequences in a list have the same length.\n",
    "\n",
    "maxlen = 20            # 20 word ka sentence hoga max\n",
    "\n",
    "from tensorflow.keras import preprocessing\n",
    "x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen)\n",
    "x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen)\n",
    "\n",
    "print(x_train.shape)\n",
    "print(y_train.shape)\n",
    "print(x_test.shape)\n",
    "print(y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_shape = x_train.shape[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding (Embedding)        (None, 20, 8)             80000     \n",
      "_________________________________________________________________\n",
      "flatten (Flatten)            (None, 160)               0         \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 1)                 161       \n",
      "=================================================================\n",
      "Total params: 80,161\n",
      "Trainable params: 80,161\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "Epoch 1/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.6715 - acc: 0.6185 - val_loss: 0.6287 - val_acc: 0.6938\n",
      "Epoch 2/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.5579 - acc: 0.7475 - val_loss: 0.5381 - val_acc: 0.7268\n",
      "Epoch 3/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.4700 - acc: 0.7886 - val_loss: 0.5059 - val_acc: 0.7402\n",
      "Epoch 4/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.4218 - acc: 0.8133 - val_loss: 0.4955 - val_acc: 0.7514\n",
      "Epoch 5/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3885 - acc: 0.8294 - val_loss: 0.4946 - val_acc: 0.7528\n",
      "Epoch 6/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3618 - acc: 0.8456 - val_loss: 0.4981 - val_acc: 0.7512\n",
      "Epoch 7/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3383 - acc: 0.8584 - val_loss: 0.5050 - val_acc: 0.7504\n",
      "Epoch 8/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3174 - acc: 0.8690 - val_loss: 0.5141 - val_acc: 0.7496\n",
      "Epoch 9/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.2980 - acc: 0.8781 - val_loss: 0.5227 - val_acc: 0.7440\n",
      "Epoch 10/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.2799 - acc: 0.8878 - val_loss: 0.5335 - val_acc: 0.7478\n"
     ]
    }
   ],
   "source": [
    "# Sequential Model\n",
    "\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Flatten, Dense\n",
    "from tensorflow.keras.layers import Embedding\n",
    "\n",
    "model = Sequential()\n",
    "model.add(Embedding(10000, 8, input_length=20)) # max_features = 10000 sentences, 8 ? # maxlen = 20 max word\n",
    "model.add(Flatten())\n",
    "model.add(Dense(1, activation='sigmoid'))\n",
    "model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])\n",
    "model.summary()\n",
    "\n",
    "history = model.fit(x_train, y_train,epochs=10,batch_size=32,validation_split=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"functional_3\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_2 (InputLayer)         [(None, 20)]              0         \n",
      "_________________________________________________________________\n",
      "embedding_1 (Embedding)      (None, 20, 8)             80000     \n",
      "_________________________________________________________________\n",
      "flatten_1 (Flatten)          (None, 160)               0         \n",
      "_________________________________________________________________\n",
      "dense_4 (Dense)              (None, 1)                 161       \n",
      "=================================================================\n",
      "Total params: 80,161\n",
      "Trainable params: 80,161\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "Epoch 1/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.6708 - acc: 0.6194 - val_loss: 0.6266 - val_acc: 0.6880\n",
      "Epoch 2/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.5494 - acc: 0.7502 - val_loss: 0.5324 - val_acc: 0.7272\n",
      "Epoch 3/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.4655 - acc: 0.7886 - val_loss: 0.5053 - val_acc: 0.7470\n",
      "Epoch 4/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.4228 - acc: 0.8105 - val_loss: 0.4987 - val_acc: 0.7502\n",
      "Epoch 5/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3930 - acc: 0.8268 - val_loss: 0.4974 - val_acc: 0.7524\n",
      "Epoch 6/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3675 - acc: 0.8390 - val_loss: 0.5016 - val_acc: 0.7520\n",
      "Epoch 7/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3451 - acc: 0.8530 - val_loss: 0.5064 - val_acc: 0.7518\n",
      "Epoch 8/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3240 - acc: 0.8637 - val_loss: 0.5133 - val_acc: 0.7490\n",
      "Epoch 9/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.3045 - acc: 0.8768 - val_loss: 0.5220 - val_acc: 0.7468\n",
      "Epoch 10/10\n",
      "625/625 [==============================] - 1s 1ms/step - loss: 0.2858 - acc: 0.8852 - val_loss: 0.5311 - val_acc: 0.7382\n"
     ]
    }
   ],
   "source": [
    "# Functional Model on single input and single output \n",
    "\n",
    "from tensorflow.keras.models import Model\n",
    "from tensorflow.keras import Input\n",
    "from tensorflow.keras import layers\n",
    "\n",
    "text_input = Input(shape=(input_shape))\n",
    "embedded_text = layers.Embedding(10000, 8, input_length=20)(text_input)\n",
    "x = layers.Flatten()(embedded_text)\n",
    "output_tensor = layers.Dense(1, activation='sigmoid')(x)\n",
    "model = Model(text_input, output_tensor)\n",
    "model.summary()\n",
    "\n",
    "model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])\n",
    "\n",
    "history = model.fit(x_train, y_train,epochs=10,batch_size=32,validation_split=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
